home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 51 / Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso / -in_the_mag- / workbench / term_4.8 / extras / source / gtlayout-source.lha / LTP_TabClass.c < prev    next >
C/C++ Source or Header  |  1997-05-08  |  18KB  |  836 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1997 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #include "Assert.h"
  15.  
  16. #if defined(DO_TAB_KIND)
  17.  
  18. #define TIA_Labels        (TAG_USER+0x90000)
  19. #define TIA_Font        (TAG_USER+0x90001)
  20. #define TIA_Screen        (TAG_USER+0x90002)
  21. #define TIA_Index        (TAG_USER+0x90003)
  22. #define TIA_DrawInfo    (TAG_USER+0x90004)
  23. #define TIA_SizeType    (TAG_USER+0x90005)
  24.  
  25. STATIC VOID
  26. DrawCap(struct RastPort *RPort,LONG Left,LONG Top,LONG Width,LONG Height,BOOL Flip)
  27. {
  28.     LONG x,y,da,MidX,MidY,r,Full,Push,Mult;
  29.  
  30.     Full = Height;
  31.  
  32.     Height = Width;
  33.  
  34.     MidX = Left;
  35.     MidY = Top + Height - 1;
  36.  
  37.     r = Height - 1;
  38.  
  39.     x = 0;
  40.     y = r;
  41.     da = r - 1;
  42.  
  43.     if(Flip)
  44.     {
  45.         Push = Width - 1;
  46.         Mult = -1;
  47.     }
  48.     else
  49.     {
  50.         Push = 0;
  51.         Mult = 1;
  52.     }
  53.  
  54.     do
  55.     {
  56.         if(da < 0)
  57.         {
  58.             y--;
  59.  
  60.             da += y * 2;
  61.         }
  62.  
  63.         WritePixel(RPort,Left + Push + Mult * (x + MidX - Left),-y + MidY);
  64.         WritePixel(RPort,Left + Push + Mult * (y + MidX - Left),-x + MidY);
  65.  
  66.         da -= (1 + x * 2);
  67.  
  68.         x++;
  69.     }
  70.     while(x <= y);
  71.  
  72.     Left += Width - 1 - Push;
  73.  
  74. /*    This is what it used to be. Easily catches fire, take care
  75.  
  76.     if(Flip)
  77.     {
  78.         do
  79.         {
  80.             if(da < 0)
  81.             {
  82.                 y--;
  83.  
  84.                 da += y * 2;
  85.             }
  86.  
  87.             WritePixel(RPort,Left + Width - 1 - (x + MidX - Left),-y + MidY);
  88.             WritePixel(RPort,Left + Width - 1 - (y + MidX - Left),-x + MidY);
  89.  
  90.             da -= (1 + x * 2);
  91.  
  92.             x++;
  93.         }
  94.         while(x <= y);
  95.     }
  96.     else
  97.     {
  98.         do
  99.         {
  100.             if(da < 0)
  101.             {
  102.                 y--;
  103.  
  104.                 da += y * 2;
  105.             }
  106.  
  107.             WritePixel(RPort,x + MidX,-y + MidY);
  108.             WritePixel(RPort,y + MidX,-x + MidY);
  109.  
  110.             da -= (1 + x * 2);
  111.  
  112.             x++;
  113.         }
  114.         while(x <= y);
  115.  
  116.         Left += Width - 1;
  117.     }
  118. */
  119.     LTP_DrawLine(RPort,Left,Top + Height,Left,Top + Full - 1);
  120. }
  121.  
  122. STATIC VOID
  123. RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,LONG Pull)
  124. {
  125.     LONG    Width,Height;
  126.     LONG    i;
  127.     LONG    Pen;
  128.  
  129.     Width    = Info->TabWidth;
  130.     Height    = Info->TabHeight;
  131.  
  132.     SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
  133.  
  134.     for(i = 0 ; i < 4 ; i++)
  135.     {
  136.         if(i & 1)
  137.         {
  138.             if(Pens[SHINEPEN] == Pens[SHADOWPEN])
  139.                 Pen = BACKGROUNDPEN;
  140.             else
  141.                 Pen = SHADOWPEN;
  142.         }
  143.         else
  144.             Pen = SHINEPEN;
  145.  
  146.         LTP_SetAPen(&Info->RPort,Pens[Pen]);
  147.  
  148.         LTP_DrawLine(&Info->RPort,0,Height - 1 - i,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
  149.     }
  150.  
  151.     for(i = Info->Count - 1 ; i >= 0 ; i--)
  152. //    for(i = 0 ; i < Info->Count ; i++)
  153.     {
  154.         if(i != Info->Current)
  155.             BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
  156.     }
  157.  
  158.     BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
  159.  
  160.     WaitBlit();
  161.  
  162.     BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
  163. }
  164.  
  165. STATIC VOID
  166. SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  167. {
  168.     TabInfo            *Info = INST_DATA(class,gadget);
  169.     struct TagItem    *Tag;
  170.     BOOL             NeedRefresh = FALSE;
  171.     BOOL             Disabled;
  172.  
  173.     Disabled = (BOOL)((gadget->Flags & GFLG_DISABLED) != 0);
  174.  
  175.     if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
  176.     {
  177.         if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
  178.             NeedRefresh = TRUE;
  179.     }
  180.  
  181.     if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
  182.     {
  183.         LONG Index = Tag->ti_Data;
  184.  
  185.         if(Index >= Info->Count)
  186.             Index = Info->Count - 1;
  187.  
  188.         if(Index != Info->Current)
  189.         {
  190.             Info->Initial = Info->Current = Index;
  191.  
  192.             NeedRefresh = TRUE;
  193.         }
  194.     }
  195.  
  196.     if(NeedRefresh)
  197.     {
  198.         struct RastPort *RPort;
  199.  
  200.         if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
  201.         {
  202.             DoMethod((Object *)gadget,GM_RENDER,SetInfo->ops_GInfo,RPort,GREDRAW_REDRAW);
  203.  
  204.             ReleaseGIRPort(RPort);
  205.         }
  206.     }
  207. }
  208.  
  209. STATIC ULONG
  210. RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
  211. {
  212.     TabInfo *Info = INST_DATA(class,gadget);
  213.  
  214.     RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,RenderInfo->gpr_Redraw == GREDRAW_UPDATE ? 2 : 0);
  215.  
  216.     return(TRUE);
  217. }
  218.  
  219. STATIC VOID
  220. DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
  221. {
  222.     TabInfo *Info = INST_DATA(class,gadget);
  223.  
  224.     if(Info->Mask || Info->Tabs || Info->BitMap)
  225.         WaitBlit();
  226.  
  227.     if(Info->Mask)
  228.     {
  229.         if(Info->ChipMask)
  230.             FreeVec(Info->Mask);
  231.         else
  232.             FreeRaster(Info->Mask,Info->TabWidth,Info->TabHeight);
  233.     }
  234.  
  235.     if(Info->Tabs)
  236.     {
  237.         LONG i;
  238.  
  239.         for(i = 0 ; i < Info->Count ; i++)
  240.             LTP_DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
  241.  
  242.         FreeVec(Info->Tabs);
  243.     }
  244.  
  245.     LTP_DeleteBitMap(Info->BitMap,FALSE);
  246. }
  247.  
  248. STATIC ULONG
  249. NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  250. {
  251.     if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
  252.     {
  253.         TabInfo            *Info = INST_DATA(class,gadget);
  254.         struct TagItem    *Tag,*TagList = SetInfo->ops_AttrList;
  255.         struct TextAttr    *FontAttr;
  256.         LONG             Width,Height;
  257.         struct DrawInfo    *DrawInfo;
  258.         STRPTR            *Labels;
  259.         struct Screen    *Screen;
  260.  
  261.         Width        = 0;
  262.         Height        = 0;
  263.  
  264.         FontAttr    = NULL;
  265.         DrawInfo    = NULL;
  266.         Labels        = NULL;
  267.         Screen        = NULL;
  268.  
  269.         memset(Info,0,sizeof(TabInfo));
  270.  
  271.         while(Tag = NextTagItem(&TagList))
  272.         {
  273.             switch(Tag->ti_Tag)
  274.             {
  275.                 case GA_Width:
  276.                     Width = Tag->ti_Data;
  277.                     break;
  278.  
  279.                 case GA_Height:
  280.                     Height = Tag->ti_Data;
  281.                     break;
  282.  
  283.                 case TIA_Labels:
  284.                     Labels = (STRPTR *)Tag->ti_Data;
  285.                     break;
  286.  
  287.                 case TIA_Font:
  288.                     FontAttr = (struct TextAttr *)Tag->ti_Data;
  289.                     break;
  290.  
  291.                 case TIA_Screen:
  292.                     Screen = (struct Screen *)Tag->ti_Data;
  293.                     break;
  294.  
  295.                 case TIA_Index:
  296.                     Info->Current = Tag->ti_Data;
  297.                     break;
  298.  
  299.                 case TIA_DrawInfo:
  300.                     DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  301.                     break;
  302.             }
  303.         }
  304.  
  305.         if(Labels)
  306.         {
  307.             while(Labels[Info->Count])
  308.                 Info->Count++;
  309.         }
  310.  
  311.         if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
  312.         {
  313.             struct TextFont *Font;
  314.  
  315.             if(Font = OpenFont(FontAttr))
  316.             {
  317.                 struct RastPort *RPort = &Info->RPort;
  318.  
  319.                 InitRastPort(RPort);
  320.  
  321.                 SetFont(RPort,Font);
  322.  
  323.                 if(Height >= RPort->TxHeight + 11)
  324.                 {
  325.                     LONG i,Len,MaxWidth,Remain;
  326.                     LONG Lean;
  327.  
  328.                     if(Info->Current < 0)
  329.                         Info->Current = 0;
  330.                     else
  331.                     {
  332.                         if(Info->Current >= Info->Count)
  333.                             Info->Current = Info->Count - 1;
  334.                     }
  335.  
  336.                     Lean = (TextLength(RPort,"O",1) + 1) / 2;
  337.  
  338.                     Info->Thick    = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  339.  
  340.                     if(Info->Thick < 1)
  341.                         Info->Thick = 1;
  342.  
  343.                     for(i = MaxWidth = 0 ; i < Info->Count ; i++)
  344.                     {
  345.                         if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  346.                             MaxWidth = Len;
  347.                     }
  348.  
  349.                     MaxWidth = Info->Thick + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + Info->Thick;
  350.  
  351.                     Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
  352.  
  353.                     if(Remain >= Info->Count - 1)
  354.                     {
  355.                         if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
  356.                         {
  357.                             STATIC BYTE PenNumbers[] =
  358.                             {
  359.                                 BACKGROUNDPEN,
  360.                                 SHINEPEN,
  361.                                 SHADOWPEN,
  362.                                 TEXTPEN
  363.                             };
  364.  
  365.                             struct BitMap     Mask;
  366.                             LONG             Depth;
  367.                             LONG             MaxPen;
  368.                             UWORD            *Pens = DrawInfo->dri_Pens;
  369.                             BOOL             GotIt = TRUE;
  370.  
  371.                             memset(&Mask,0,sizeof(Mask));
  372.  
  373.                             for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
  374.                             {
  375.                                 if(Pens[PenNumbers[i]] > MaxPen)
  376.                                     MaxPen = Pens[PenNumbers[i]];
  377.                             }
  378.  
  379.                             for(i = 1 ; i < 9 ; i++)
  380.                             {
  381.                                 if(MaxPen < (1 << i))
  382.                                 {
  383.                                     Depth = i;
  384.                                     break;
  385.                                 }
  386.                             }
  387.  
  388.                             Info->TabWidth    = MaxWidth;
  389.                             Info->TabHeight    = 4 + RPort->TxHeight + 5;
  390.  
  391.                             InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
  392.  
  393.                             Mask.Planes[1] = NULL;
  394.  
  395.                             for(i = 0 ; GotIt && i < 2 ; i++)
  396.                             {
  397.                                 if(!(Mask.Planes[i] = (PLANEPTR)AllocRaster(Info->TabWidth,Info->TabHeight)))
  398.                                     GotIt = FALSE;
  399.                             }
  400.  
  401.                             if(GotIt)
  402.                             {
  403.                                 ULONG Type;
  404.  
  405.                                 Type = MEMF_CHIP;
  406.  
  407.                                 for(i = 0 ; i < 2 ; i++)
  408.                                     Type &= TypeOfMem(Mask.Planes[i]);
  409.  
  410.                                 if(!(Type & MEMF_CHIP))
  411.                                 {
  412.                                     LONG PageSize;
  413.  
  414.                                     for(i = 0 ; i < 2 ; i++)
  415.                                     {
  416.                                         FreeRaster(Mask.Planes[i],Info->TabWidth,Info->TabHeight);
  417.                                         Mask.Planes[i] = NULL;
  418.                                     }
  419.  
  420.                                     PageSize = Mask.BytesPerRow * Mask.Rows;
  421.  
  422.                                     for(i = 0 ; i < 2 ; i++)
  423.                                     {
  424.                                         if(!(Mask.Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP)))
  425.                                             GotIt = FALSE;
  426.                                     }
  427.  
  428.                                     Info->ChipMask = TRUE;
  429.                                 }
  430.                             }
  431.  
  432.                             for(i = 0 ; GotIt && i < Info->Count ; i++)
  433.                             {
  434.                                 if(!(Info->Tabs[i].BitMap = LTP_CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
  435.                                     GotIt = FALSE;
  436.                             }
  437.  
  438.                             if(GotIt)
  439.                             {
  440.                                 Depth = LTP_GetDepth(Screen->RastPort.BitMap);
  441.  
  442.                                 if(!(Info->BitMap = LTP_CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
  443.                                     GotIt = FALSE;
  444.                             }
  445.  
  446.                             if(GotIt)
  447.                             {
  448.                                 struct TmpRas     TmpRas;
  449.                                 LONG             j,Len,Offset,Pos;
  450.  
  451.                                 InitTmpRas(&TmpRas,Mask.Planes[1],RASSIZE(Info->TabWidth,Info->TabHeight));
  452.  
  453.                                 RPort->TmpRas    = &TmpRas;
  454.                                 RPort->BitMap    = &Mask;
  455.  
  456.                                 SetRast(RPort,0);
  457.  
  458.                                 LTP_SetPens(RPort,1,0,JAM1);
  459.  
  460.                                 DrawCap(RPort,0,0,Lean,Info->TabHeight,TRUE);
  461.                                 LTP_DrawLine(RPort,Lean,0,Info->TabWidth - (Lean + 1),0);
  462.  
  463.                                 DrawCap(RPort,Info->TabWidth - Lean,0,Lean,Info->TabHeight,FALSE);
  464.                                 LTP_DrawLine(RPort,0,Info->TabHeight - 1,Info->TabWidth - 1,Info->TabHeight - 1);
  465.  
  466.                                 Flood(RPort,1,Info->TabWidth / 2,Info->TabHeight / 2);
  467.  
  468.                                 LTP_SetAPen(RPort,0);
  469.  
  470.                                 for(i = 0 ; i < 2 ; i++)
  471.                                 {
  472.                                     for(j = 0 ; j < Info->Thick ; j++)
  473.                                         WritePixel(RPort,j,Info->TabHeight - 1 - i);
  474.  
  475.                                     for(j = 0 ; j < Info->Thick ; j++)
  476.                                         WritePixel(RPort,Info->TabWidth - 1 - j,Info->TabHeight - 1 - i);
  477.                                 }
  478.  
  479.                                 WaitBlit();
  480.  
  481.                                 if(Info->ChipMask)
  482.                                     FreeVec(Mask.Planes[1]);
  483.                                 else
  484.                                     FreeRaster(Mask.Planes[1],Info->TabWidth,Info->TabHeight);
  485.  
  486.                                     // *VERY* important; leaving a dead TmpRas around will
  487.                                     // cause problems with Text() later as Gfx may use
  488.                                     // RPort->TmpRas for buffering.
  489.  
  490.                                 RPort->TmpRas = NULL;
  491.  
  492.                                 Offset = (Width - Info->Thick * 5) / Info->Count;
  493.  
  494.                                 while(Offset > 0 && Offset * (Info->Count - 1) + Info->TabWidth >= Width - Info->Thick * 5)
  495.                                     Offset--;
  496.  
  497.                                 if(Offset > Info->TabWidth + Info->Thick)
  498.                                     Offset = Info->TabWidth + Info->Thick;
  499.  
  500.                                 Pos = 2 * Info->Thick;
  501.  
  502.                                 for(i = 0 ; i < Info->Count ; i++)
  503.                                 {
  504.                                     RPort->BitMap = Info->Tabs[i].BitMap;
  505.  
  506.                                     Info->Tabs[i].Left = Pos;
  507.                                     Pos += Offset;
  508.  
  509.                                     SetRast(RPort,Pens[BACKGROUNDPEN]);
  510.  
  511.                                     LTP_SetAPen(RPort,Pens[SHINEPEN]);
  512.  
  513.                                     for(j = 0 ; j < Info->Thick ; j++)
  514.                                         DrawCap(RPort,Info->Thick + j,0,Lean,Info->TabHeight,TRUE);
  515.  
  516.                                     LTP_DrawLine(RPort,Info->Thick + Lean,0,Info->TabWidth - (Lean + 1) - Info->Thick,0);
  517.  
  518.                                     LTP_SetAPen(RPort,Pens[SHADOWPEN]);
  519.  
  520.                                     for(j = 0 ; j < Info->Thick ; j++)
  521.                                         DrawCap(RPort,Info->TabWidth - Lean - j - Info->Thick,0,Lean,Info->TabHeight,FALSE);
  522.  
  523.                                     LTP_SetAPen(RPort,Pens[TEXTPEN]);
  524.                                     Len = strlen(Labels[i]);
  525.  
  526.                                     LTP_PrintText(RPort,Labels[i],Len,(Info->TabWidth - TextLength(RPort,Labels[i],Len)) / 2,2);
  527.                                 }
  528.  
  529.                                 Info->Mask = Mask.Planes[0];
  530.  
  531.                                 Info->Offset = Offset;
  532.  
  533.                                 Info->RPort.BitMap = Info->BitMap;
  534.  
  535.                                 CloseFont(Font);
  536.  
  537.                                 return((ULONG)gadget);
  538.                             }
  539.                         }
  540.                     }
  541.                 }
  542.  
  543.                 CloseFont(Font);
  544.             }
  545.         }
  546.  
  547.         CoerceMethod(class,(Object *)gadget,OM_DISPOSE);
  548.     }
  549.  
  550.     return(0);
  551. }
  552.  
  553. STATIC ULONG
  554. InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  555. {
  556.     TabInfo    *Info    = INST_DATA(class,gadget);
  557.     ULONG     Result    = GMR_MEACTIVE;
  558.     LONG     x,y;
  559.     BOOL     Done    = FALSE;
  560.  
  561.     x = InputInfo->gpi_Mouse.X;
  562.     y = InputInfo->gpi_Mouse.Y;
  563.  
  564.     if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  565.     {
  566.         if(InputInfo->gpi_IEvent->ie_Code == MENUDOWN)
  567.         {
  568.             Result    = GMR_NOREUSE;
  569.             Done    = TRUE;
  570.         }
  571.         else
  572.         {
  573.             if(InputInfo->gpi_IEvent->ie_Code == SELECTUP)
  574.             {
  575.                 Done = TRUE;
  576.  
  577.                 if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  578.                 {
  579.                     Result = GMR_NOREUSE | GMR_VERIFY;
  580.  
  581.                     *InputInfo->gpi_Termination = Info->Current;
  582.                 }
  583.                 else
  584.                     Result = GMR_NOREUSE;
  585.             }
  586.         }
  587.     }
  588.  
  589.     if(Result == GMR_NOREUSE)
  590.     {
  591.         struct RastPort    *RPort;
  592.  
  593.         if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  594.         {
  595.             Info->Current = Info->Initial;
  596.  
  597.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_REDRAW);
  598.  
  599.             ReleaseGIRPort(RPort);
  600.         }
  601.     }
  602.  
  603.     if(!Done)
  604.     {
  605.         if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  606.         {
  607.             LONG Index,i;
  608.  
  609.             for(Index = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  610. //            for(Index = -1, i = 0 ; i < Info->Count ; i++)
  611.             {
  612.                 if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  613.                     Index = i;
  614.             }
  615.  
  616.             if(Index != Info->Current && Index != -1)
  617.             {
  618.                 struct RastPort    *RPort;
  619.  
  620.                 if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  621.                 {
  622.                     Info->Current = Index;
  623.  
  624.                     DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  625.  
  626.                     ReleaseGIRPort(RPort);
  627.                 }
  628.             }
  629.         }
  630.     }
  631.  
  632.     return(Result);
  633. }
  634.  
  635. STATIC ULONG
  636. ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  637. {
  638.     TabInfo            *Info = INST_DATA(class,gadget);
  639.     struct RastPort    *RPort;
  640.  
  641.     if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  642.     {
  643.         LONG Current,i;
  644.         LONG x;
  645.  
  646.         x = InputInfo->gpi_Mouse.X;
  647.  
  648.         for(Current = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  649. //        for(Current = -1, i = 0 ; i < Info->Count ; i++)
  650.         {
  651.             if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  652.                 Current = i;
  653.         }
  654.  
  655.         Info->Initial = Info->Current;
  656.  
  657.         if(Current != Info->Current && Current != -1)
  658.         {
  659.             Info->Current = Current;
  660.  
  661.             DoMethod((Object *)gadget,GM_RENDER,InputInfo->gpi_GInfo,RPort,GREDRAW_UPDATE);
  662.         }
  663.  
  664.         ReleaseGIRPort(RPort);
  665.  
  666.         return(GMR_MEACTIVE);
  667.     }
  668.     else
  669.         return(GMR_NOREUSE);
  670. }
  671.  
  672. STATIC ULONG
  673. InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
  674. {
  675.     TabInfo            *Info = INST_DATA(class,gadget);
  676.     struct RastPort    *RPort;
  677.     LONG             Index;
  678.  
  679.     if(InactiveInfo->gpgi_Abort)
  680.         Index = Info->Initial;
  681.     else
  682.         Index = Info->Current;
  683.  
  684.     if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
  685.     {
  686.         Info->Current = Index;
  687.  
  688.         DoMethod((Object *)gadget,GM_RENDER,InactiveInfo->gpgi_GInfo,RPort,GREDRAW_REDRAW);
  689.  
  690.         ReleaseGIRPort(RPort);
  691.     }
  692.  
  693.     return(0);
  694. }
  695.  
  696. BOOL
  697. LTP_ObtainTabSize(struct IBox *Box,...)
  698. {
  699.     va_list             VarArgs;
  700.     struct TagItem    *TagList,*Tag;
  701.     struct TextAttr    *FontAttr;
  702.     struct DrawInfo    *DrawInfo;
  703.     STRPTR            *Labels;
  704.     LONG             Count;
  705.     LONG             SizeType;
  706.     BOOL             Success;
  707.  
  708.     Success = FALSE;
  709.  
  710.     va_start(VarArgs,Box);
  711.  
  712.     TagList = (struct TagItem *)VarArgs;
  713.  
  714.     SizeType = GDOMAIN_NOMINAL;
  715.     FontAttr = NULL;
  716.     DrawInfo = NULL;
  717.     Labels = NULL;
  718.  
  719.     while(Tag = NextTagItem(&TagList))
  720.     {
  721.         switch(Tag->ti_Tag)
  722.         {
  723.             case TIA_Labels:
  724.                 Labels = (STRPTR *)Tag->ti_Data;
  725.                 break;
  726.  
  727.             case TIA_Font:
  728.                 FontAttr = (struct TextAttr *)Tag->ti_Data;
  729.                 break;
  730.  
  731.             case TIA_DrawInfo:
  732.                 DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  733.                 break;
  734.  
  735.             case TIA_SizeType:
  736.                 SizeType = Tag->ti_Data;
  737.                 break;
  738.         }
  739.     }
  740.  
  741.     Count = 0;
  742.  
  743.     if(Labels)
  744.     {
  745.         while(Labels[Count])
  746.             Count++;
  747.     }
  748.  
  749.     if(DrawInfo && FontAttr && Labels && Count)
  750.     {
  751.         struct TextFont *Font;
  752.  
  753.         if(Font = OpenFont(FontAttr))
  754.         {
  755.             struct RastPort    RastPort,*RPort = &RastPort;
  756.             LONG            i,Len,MaxWidth;
  757.             LONG            Lean,Thick;
  758.  
  759.             InitRastPort(RPort);
  760.  
  761.             SetFont(RPort,Font);
  762.  
  763.             Box->Left    = 0;
  764.             Box->Top    = 0;
  765.             Box->Height    = RPort->TxHeight + 11;
  766.  
  767.             Lean = (TextLength(RPort,"O",1) + 1) / 2;
  768.  
  769.             Thick = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
  770.  
  771.             if(Thick < 1)
  772.                 Thick = 1;
  773.  
  774.             for(i = MaxWidth = 0 ; i < Count ; i++)
  775.             {
  776.                 if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  777.                     MaxWidth = Len;
  778.             }
  779.  
  780.             MaxWidth = 2 + (Lean + Thick - 1 + Thick + MaxWidth + Thick + Lean + Thick - 1) + 2;
  781.  
  782.             if(SizeType == GDOMAIN_MINIMUM && Count > 1)
  783.                 Box->Width = 2 * Thick + MaxWidth + (Count - 1) * (Thick * 4) + Thick * 3;
  784.             else
  785.                 Box->Width = 2 * Thick + Count * (MaxWidth + Thick) + Thick * 2;
  786.  
  787.             CloseFont(Font);
  788.  
  789.             Success = TRUE;
  790.         }
  791.     }
  792.  
  793.     va_end(VarArgs);
  794.  
  795.     return(Success);
  796. }
  797.  
  798. ULONG SAVE_DS ASM
  799. LTP_TabClassDispatcher(REG(a0) struct IClass *class,REG(a2) Object *object,REG(a1) Msg msg)
  800. {
  801.     switch(msg->MethodID)
  802.     {
  803.         case OM_NEW:
  804.             return(NewMethod(class,(struct Gadget *)object,(struct opSet *)msg));
  805.  
  806.         case OM_UPDATE:
  807.         case OM_SET:
  808.             SetMethod(class,(struct Gadget *)object,(struct opSet *)msg);
  809.             break;
  810.  
  811.         case GM_RENDER:
  812.             return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
  813.  
  814.         case GM_HITTEST:
  815.             return(GMR_GADGETHIT);
  816.  
  817.         case GM_GOINACTIVE:
  818.             return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
  819.  
  820.         case GM_HANDLEINPUT:
  821.             return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  822.  
  823.         case GM_GOACTIVE:
  824.             return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  825.  
  826.         case OM_DISPOSE:
  827.             DisposeMethod(class,(struct Gadget *)object,msg);
  828.  
  829.             // Falls down through to the default case...
  830.     }
  831.  
  832.     return(DoSuperMethodA(class,object,msg));
  833. }
  834.  
  835. #endif    // defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  836.